/* Copyright (c) 2022-2022, LiWangQian<liwangqian@huawei.com> All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this list of
 *    conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
 *    of conditions and the following disclaimer in the documentation and/or other materials
 *    provided with the distribution.
 *
 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
 *    to endorse or promote products derived from this software without specific prior written
 *    permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#ifndef LIBCFGM_STRING_H
#define LIBCFGM_STRING_H

#include <stddef.h>
#include <stdbool.h>
#include <string.h>

#ifdef __cplusplus
extern "C" {
#endif

typedef struct cfgm_string_ref {
    const char *buf; //! reference, may not '\0' terminate
    unsigned int size;
} cfgm_string_ref_t;

static inline bool cfgm_string_ref_is_same(
    const cfgm_string_ref_t *lhs, const cfgm_string_ref_t *rhs)
{
    if (lhs->size != rhs->size) return false;
    return strncmp(lhs->buf, rhs->buf, lhs->size) == 0;
}

typedef struct cfgm_string {
    unsigned int max_size;
    unsigned int size;
    char *buf;
} cfgm_string_t;

/// @brief 初始化一个字符串结构体，申请字符buf内存
/// @param size 字符buf的最大长度
/// @param inst 字符串实例
/// @return 申请内存成功则返回CFGM_OK，否则返回CFGM_EMEM
int cfgm_string_create(unsigned int size, cfgm_string_t *inst);

/// @brief 释放字符串实例占用的内存
/// @param inst 字符串实例
void cfgm_string_destroy(cfgm_string_t *inst);

static inline bool cfgm_string_valid(const cfgm_string_t *inst)
{
    return inst ?
        (inst->max_size > 0) &&
        (inst->max_size >= inst->size) &&
        (inst->buf != NULL) : false;
}

static inline bool cfgm_string_empty(const cfgm_string_t *inst)
{
    return inst ? (inst->size == 0) : false;
}

static inline bool cfgm_string_full(const cfgm_string_t *inst)
{
    return inst ? (inst->size == inst->max_size) : true;
}

static inline unsigned int cfgm_string_max_size(const cfgm_string_t *inst)
{
    return inst ? inst->max_size : 0;
}

static inline unsigned int cfgm_string_size(const cfgm_string_t *inst)
{
    return inst ? inst->size : 0;
}

static inline unsigned int cfgm_string_available_size(const cfgm_string_t *inst)
{
    return inst ? (inst->max_size - inst->size) : 0;
}

static inline const char* cfgm_string_cstr(const cfgm_string_t *inst)
{
    return inst ? inst->buf : NULL;
}

#ifdef __cplusplus
}
#endif

#endif /* LIBCFGM_STRING_H */
